React์ useDeferredValue ํ ์ฌ์ธต ๋ถ์. UI ์ง์ฐ ๋ฌธ์ ํด๊ฒฐ, ๋์์ฑ ์ดํด, useTransition๊ณผ์ ๋น๊ต๋ฅผ ํตํด ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ๋ ๋น ๋ฅธ ์ฑ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.
React์ useDeferredValue: ๋ ผ๋ธ๋กํน UI ์ฑ๋ฅ์ ์ํ ์๋ฒฝ ๊ฐ์ด๋
ํ๋ ์น ๊ฐ๋ฐ์ ์ธ๊ณ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ฌด์๋ณด๋ค ์ค์ํฉ๋๋ค. ๋น ๋ฅด๊ณ ๋ฐ์์ฑ์ด ์ข์ ์ธํฐํ์ด์ค๋ ๋ ์ด์ ์ฌ์น๊ฐ ์๋๋ผ ํ์์ ์ธ ๊ธฐ๋์น์ ๋๋ค. ์ ์ธ๊ณ ์ฌ์ฉ์๋ค์ด ์ฌ์ฉํ๋ ๋ค์ํ ์ฅ์น์ ๋คํธ์ํฌ ํ๊ฒฝ์์, ์ง์ฐ๋๊ณ ๋ฒ๋ฒ ์ด๋ UI๋ ์ฌ๋ฐฉ๋ฌธ ๊ณ ๊ฐ๊ณผ ์ดํ ๊ณ ๊ฐ์ ๊ฐ๋ฅด๋ ์ฐจ์ด๊ฐ ๋ ์ ์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ React 18์ ๋์์ฑ ๊ธฐ๋ฅ, ํนํ useDeferredValue ํ ์ด ํ๋๋ฅผ ๋ฐ๊ฟ๋๋ค.
๋๊ท๋ชจ ๋ชฉ๋ก์ ํํฐ๋งํ๋ ๊ฒ์ ํ๋, ์ค์๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ๋๋ ๋ฐ์ดํฐ ๊ทธ๋ฆฌ๋, ๋๋ ๋ณต์กํ ๋์๋ณด๋๋ฅผ ๊ฐ์ถ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํด ๋ณธ ์ ์ด ์๋ค๋ฉด, ๋์ฐํ UI ํ๋ฆฌ์ง(๋ฉ์ถค ํ์)์ ๊ฒฝํํด ๋ณด์ จ์ ๊ฒ์ ๋๋ค. ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ ์์ฃผ ์งง์ ์๊ฐ ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด๊ฐ ์๋ตํ์ง ์๋ ํ์์ด์ฃ . ์ด๋ React์ ์ ํต์ ์ธ ๋ ๋๋ง ๋ฐฉ์์ด ๋ธ๋กํน(blocking) ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค. ์ํ ์ ๋ฐ์ดํธ๊ฐ ๋ฆฌ๋ ๋๋ง์ ์ ๋ฐํ๋ฉด, ๊ทธ๊ฒ์ด ๋๋ ๋๊น์ง ๋ค๋ฅธ ์ด๋ค ์์ ๋ ์ผ์ด๋ ์ ์์ต๋๋ค.
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋์์๋ useDeferredValue ํ ์ ๋ํด ๊น์ด ํ๊ณ ๋ค ๊ฒ์ ๋๋ค. ์ด ํ ์ด ํด๊ฒฐํ๋ ๋ฌธ์ , React์ ์๋ก์ด ๋์์ฑ ์์ง๊ณผ ํจ๊ป ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ์๋ํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ํ์ฉํ์ฌ ๋ง์ ์์ ์ ์ํํ ๋์กฐ์ฐจ๋ ๋น ๋ฅด๋ค๊ณ ๋๊ปด์ง๋ ๋๋๋๋ก ๋ฐ์์ฑ์ด ์ข์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ํ๊ตฌํ ๊ฒ์ ๋๋ค. ์ค์ ์์ , ๊ณ ๊ธ ํจํด, ๊ทธ๋ฆฌ๊ณ ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ํต์ฌ์ ์ธ ๋ชจ๋ฒ ์ฌ๋ก๋ค์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.
ํต์ฌ ๋ฌธ์ ์ดํดํ๊ธฐ: ๋ธ๋กํน UI
ํด๊ฒฐ์ฑ ์ ๊ฐ์น๋ฅผ ์ ๋๋ก ์๊ธฐ ์ ์, ์ฐ๋ฆฌ๋ ๋จผ์ ๋ฌธ์ ๋ฅผ ์์ ํ ์ดํดํด์ผ ํฉ๋๋ค. React 18 ์ด์ ๋ฒ์ ์์ ๋ ๋๋ง์ ๋๊ธฐ์ ์ด๊ณ ์ค๋จ ๋ถ๊ฐ๋ฅํ ํ๋ก์ธ์ค์์ต๋๋ค. 1์ฐจ์ ๋๋ก๋ฅผ ์์ํด ๋ณด์ธ์: ์ผ๋จ ์ฐจ(๋ ๋๋ง) ํ ๋๊ฐ ์ง์ ํ๋ฉด, ๊ทธ ์ฐจ๊ฐ ๋์ ๋๋ฌํ ๋๊น์ง ๋ค๋ฅธ ์ฐจ๋ ์ง๋๊ฐ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก React๊ฐ ์๋ํ๋ ๋ฐฉ์์ด์์ต๋๋ค.
์ ํ์ ์ธ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ด ์๋ค: ๊ฒ์ ๊ฐ๋ฅํ ์ํ ๋ชฉ๋ก. ์ฌ์ฉ์๊ฐ ๊ฒ์์ฐฝ์ ์ ๋ ฅํ๋ฉด, ๊ทธ ์๋์ ์๋ ์์ฒ ๊ฐ์ ์์ดํ ๋ชฉ๋ก์ด ์ ๋ ฅ๊ฐ์ ๋ฐ๋ผ ํํฐ๋ง๋ฉ๋๋ค.
์ผ๋ฐ์ ์ธ (๊ทธ๋ฆฌ๊ณ ๋๋ฆฐ) ๊ตฌํ
React 18 ์ด์ ์ด๋ ๋์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ์์์ ๋์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
์ปดํฌ๋ํธ ๊ตฌ์กฐ:
ํ์ผ: SearchPage.js
import React, { useState } from 'react';
import ProductList from './ProductList';
import { generateProducts } from './data'; // a function that creates a large array
const allProducts = generateProducts(20000); // Let's imagine 20,000 products
function SearchPage() {
const [query, setQuery] = useState('');
const filteredProducts = allProducts.filter(product => {
return product.name.toLowerCase().includes(query.toLowerCase());
});
function handleChange(e) {
setQuery(e.target.value);
}
return (
์ ์ด๊ฒ์ด ๋๋ฆด๊น์?
์ฌ์ฉ์์ ํ๋์ ๋ฐ๋ผ๊ฐ ๋ด ์๋ค:
- ์ฌ์ฉ์๊ฐ 'a'๋ผ๋ ๊ธ์๋ฅผ ์ ๋ ฅํฉ๋๋ค.
- onChange ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ฌ handleChange๋ฅผ ํธ์ถํฉ๋๋ค.
- setQuery('a')๊ฐ ํธ์ถ๋ฉ๋๋ค. ์ด๋ SearchPage ์ปดํฌ๋ํธ์ ๋ฆฌ๋ ๋๋ง์ ์์ฝํฉ๋๋ค.
- React๊ฐ ๋ฆฌ๋ ๋๋ง์ ์์ํฉ๋๋ค.
- ๋ ๋๋ง ๊ณผ์ ์์
const filteredProducts = allProducts.filter(...)
๋ผ์ธ์ด ์คํ๋ฉ๋๋ค. ์ด๊ฒ์ด ๋น์ฉ์ด ๋ง์ด ๋๋ ๋ถ๋ถ์ ๋๋ค. 20,000๊ฐ์ ์์ดํ ๋ฐฐ์ด์ ๊ฐ๋จํ 'includes' ํ์ธ์ผ๋ก ํํฐ๋งํ๋ ๊ฒ์กฐ์ฐจ ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค. - ์ด ํํฐ๋ง์ด ์งํ๋๋ ๋์, ๋ธ๋ผ์ฐ์ ์ ๋ฉ์ธ ์ค๋ ๋๋ ์์ ํ ์ ์ ๋ฉ๋๋ค. ์๋ก์ด ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ ์๋, ์ ๋ ฅ ํ๋๋ฅผ ์๊ฐ์ ์ผ๋ก ์ ๋ฐ์ดํธํ ์๋, ๋ค๋ฅธ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์๋ ์์ต๋๋ค. UI๊ฐ ๋ธ๋กํน(blocked)๋ ๊ฒ์ ๋๋ค.
- ํํฐ๋ง์ด ๋๋๋ฉด, React๋ ProductList ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ธฐ ์์ํฉ๋๋ค. ์ด ๋ํ ์์ฒ ๊ฐ์ DOM ๋ ธ๋๋ฅผ ๋ ๋๋งํ๋ ๊ฒฝ์ฐ ๋ฌด๊ฑฐ์ด ์์ ์ผ ์ ์์ต๋๋ค.
- ๋ง์นจ๋ด ์ด ๋ชจ๋ ์์ ์ด ๋๋๊ณ DOM์ด ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์ฌ์ฉ์๋ ์ ๋ ฅ ์์์ 'a'๋ผ๋ ๊ธ์๊ฐ ๋ํ๋๋ ๊ฒ์ ๋ณด๊ณ ๋ชฉ๋ก์ด ์ ๋ฐ์ดํธ๋๋ ๊ฒ์ ํ์ธํฉ๋๋ค.
๋ง์ฝ ์ฌ์ฉ์๊ฐ "apple"์ฒ๋ผ ๋น ๋ฅด๊ฒ ์ ๋ ฅํ๋ค๋ฉด, ์ด ์ ์ฒด ๋ธ๋กํน ๊ณผ์ ์ด 'a'์ ๋ํด, ๊ทธ๋ฆฌ๊ณ 'ap', 'app', 'appl', 'apple'์ ๋ํด ์์ฐจ์ ์ผ๋ก ๋ฐ์ํฉ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ ์ ๋ ฅ ํ๋๊ฐ ์ฌ์ฉ์์ ํ์ดํ ์๋๋ฅผ ๋ฐ๋ผ๊ฐ์ง ๋ชปํ๊ณ ๋ฒ๋ฒ ์ด๋ ํ์ ํ ์ง์ฐ์ด ๋ฐ์ํฉ๋๋ค. ์ด๋ ํนํ ์ ์ธ๊ณ ๋ง์ ์ง์ญ์์ ํํ ์ฌ์ฉ๋๋ ์ ์ฌ์ ๊ธฐ๊ธฐ์์ ์ข์ง ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
React 18์ ๋์์ฑ(Concurrency) ์๊ฐ
React 18์ ๋์์ฑ์ ๋์ ํ์ฌ ์ด๋ฌํ ํจ๋ฌ๋ค์์ ๊ทผ๋ณธ์ ์ผ๋ก ๋ฐ๊ฟ๋๋ค. ๋์์ฑ์ ๋ณ๋ ฌ์ฑ(์ฌ๋ฌ ๊ฐ์ง ์ผ์ ๋์์ ํ๋ ๊ฒ)๊ณผ๋ ๋ค๋ฆ ๋๋ค. ๋์ , React๊ฐ ๋ ๋๋ง์ ์ผ์ ์ค์ง, ์ฌ๊ฐ ๋๋ ํฌ๊ธฐํ ์ ์๋ ๋ฅ๋ ฅ์ ์๋ฏธํฉ๋๋ค. ์ด์ 1์ฐจ์ ๋๋ก์ ์ถ์ ์ฐจ์ ๊ณผ ๊ตํต ๊ด์ ์ฌ๊ฐ ์๊ธด ์ ์ ๋๋ค.
๋์์ฑ์ ํตํด React๋ ์ ๋ฐ์ดํธ๋ฅผ ๋ ๊ฐ์ง ์ ํ์ผ๋ก ๋ถ๋ฅํ ์ ์์ต๋๋ค:
- ๊ธด๊ธ ์ ๋ฐ์ดํธ(Urgent Updates): ์ ๋ ฅ์ฐฝ์ ํ์ดํํ๊ฑฐ๋, ๋ฒํผ์ ํด๋ฆญํ๊ฑฐ๋, ์ฌ๋ผ์ด๋๋ฅผ ๋๋๊ทธํ๋ ๊ฒ์ฒ๋ผ ์ฆ๊ฐ์ ์ผ๋ก ๋๊ปด์ ธ์ผ ํ๋ ๊ฒ๋ค์ ๋๋ค. ์ฌ์ฉ์๋ ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ๊ธฐ๋ํฉ๋๋ค.
- ์ ํ ์ ๋ฐ์ดํธ(Transition Updates): UI๋ฅผ ํ ๋ทฐ์์ ๋ค๋ฅธ ๋ทฐ๋ก ์ ํํ ์ ์๋ ์ ๋ฐ์ดํธ์ ๋๋ค. ์ด๋ฌํ ์ ๋ฐ์ดํธ๋ ๋ํ๋๋ ๋ฐ ์ฝ๊ฐ์ ์๊ฐ์ด ๊ฑธ๋ ค๋ ๊ด์ฐฎ์ต๋๋ค. ๋ชฉ๋ก์ ํํฐ๋งํ๊ฑฐ๋ ์๋ก์ด ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ๋ ๊ฒ์ด ์ ํ์ ์ธ ์์ ๋๋ค.
์ด์ React๋ ๊ธด๊ธํ์ง ์์ "์ ํ" ๋ ๋๋ง์ ์์ํ ์ ์๊ณ , ๋ง์ฝ ๋ ๊ธด๊ธํ ์ ๋ฐ์ดํธ(๋ค๋ฅธ ํค ์ ๋ ฅ ๋ฑ)๊ฐ ๋ค์ด์ค๋ฉด, ์ค๋ ์คํ๋๋ ๋ ๋๋ง์ ์ผ์ ์ค์งํ๊ณ ๊ธด๊ธํ ์ ๋ฐ์ดํธ๋ฅผ ๋จผ์ ์ฒ๋ฆฌํ ๋ค์, ์์ ์ ์ฌ๊ฐํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด UI๋ ํญ์ ์ํธ์์ฉ ๊ฐ๋ฅํ ์ํ๋ฅผ ์ ์งํฉ๋๋ค. useDeferredValue ํ ์ ์ด ์๋ก์ด ํ์ ํ์ฉํ๊ธฐ ์ํ ์ฃผ์ ๋๊ตฌ์ ๋๋ค.
`useDeferredValue`๋ ๋ฌด์์ธ๊ฐ? ์์ธ ์ค๋ช
ํต์ฌ์ ์ผ๋ก, useDeferredValue๋ ์ปดํฌ๋ํธ์ ํน์ ๊ฐ์ด ๊ธด๊ธํ์ง ์๋ค๋ ๊ฒ์ React์ ์๋ ค์ฃผ๋ ํ ์ ๋๋ค. ์ด ํ ์ ๊ฐ์ ๋ฐ์์, ๊ธด๊ธํ ์ ๋ฐ์ดํธ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ "๋ค์ฒ์ง๋" ์๋ก์ด ๊ฐ์ ๋ณต์ฌ๋ณธ์ ๋ฐํํฉ๋๋ค.
๋ฌธ๋ฒ
์ด ํ ์ ์ฌ์ฉํ๊ธฐ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค:
import { useDeferredValue } from 'react';
const deferredValue = useDeferredValue(value);
์ด๊ฒ์ด ์ ๋ถ์ ๋๋ค. ๊ฐ์ ์ ๋ฌํ๋ฉด, ๊ทธ ๊ฐ์ ์ง์ฐ๋ ๋ฒ์ ์ ์ป๊ฒ ๋ฉ๋๋ค.
๋ด๋ถ ๋์ ๋ฐฉ์
๋ง๋ฒ ๊ฐ์ ๋์์ ํํค์ณ ๋ด ์๋ค. useDeferredValue(query)๋ฅผ ์ฌ์ฉํ๋ฉด React๋ ๋ค์๊ณผ ๊ฐ์ด ๋์ํฉ๋๋ค:
- ์ด๊ธฐ ๋ ๋๋ง: ์ฒซ ๋ ๋๋ง ์, deferredQuery๋ ์ด๊ธฐ query์ ๋์ผํ ๊ฐ์ ๊ฐ์ง๋๋ค.
- ๊ธด๊ธ ์ ๋ฐ์ดํธ ๋ฐ์: ์ฌ์ฉ์๊ฐ ์๋ก์ด ๋ฌธ์๋ฅผ ์ ๋ ฅํฉ๋๋ค. query ์ํ๊ฐ 'a'์์ 'ap'๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
- ๊ณ ์ฐ์ ์์ ๋ ๋๋ง: React๋ ์ฆ์ ๋ฆฌ๋ ๋๋ง์ ์์ํฉ๋๋ค. ์ด ์ฒซ ๋ฒ์งธ ๊ธด๊ธ ๋ฆฌ๋ ๋๋ง ๋์, useDeferredValue๋ ๊ธด๊ธ ์ ๋ฐ์ดํธ๊ฐ ์งํ ์ค์์ ์๊ณ ์์ต๋๋ค. ๊ทธ๋์ ์ฌ์ ํ ์ด์ ๊ฐ์ธ 'a'๋ฅผ ๋ฐํํฉ๋๋ค. ์ปดํฌ๋ํธ๋ ๋น ๋ฅด๊ฒ ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค. ์๋ํ๋ฉด ์ ๋ ฅ ํ๋์ ๊ฐ์ 'ap'๊ฐ ๋์ง๋ง(์ํ๋ก๋ถํฐ), deferredQuery์ ์์กดํ๋ UI ๋ถ๋ถ(๋๋ฆฐ ๋ชฉ๋ก)์ ์ฌ์ ํ ์ด์ ๊ฐ์ ์ฌ์ฉํ๊ณ ๋ค์ ๊ณ์ฐํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. UI๋ ๋ฐ์์ฑ์ ์ ์งํฉ๋๋ค.
- ์ ์ฐ์ ์์ ๋ ๋๋ง: ๊ธด๊ธ ๋ ๋๋ง์ด ์๋ฃ๋ ์งํ, React๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ ๋ฒ์งธ, ๊ธด๊ธํ์ง ์์ ๋ฆฌ๋ ๋๋ง์ ์์ํฉ๋๋ค. ์ด ๋ ๋๋ง์์ useDeferredValue๋ ์๋ก์ด ๊ฐ์ธ 'ap'๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ ๋๋ง์ด ๋น์ฉ์ด ๋ง์ด ๋๋ ํํฐ๋ง ์์ ์ ์ ๋ฐํฉ๋๋ค.
- ์ค๋จ ๊ฐ๋ฅ์ฑ: ์ฌ๊ธฐ๊ฐ ํต์ฌ์ ๋๋ค. ๋ง์ฝ 'ap'์ ๋ํ ์ ์ฐ์ ์์ ๋ ๋๋ง์ด ์์ง ์งํ ์ค์ผ ๋ ์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ๊ธ์('app')๋ฅผ ์ ๋ ฅํ๋ฉด, React๋ ๊ทธ ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ ๋๋ง์ ๋ฒ๋ฆฌ๊ณ ์ฒ์๋ถํฐ ๋ค์ ์์ํฉ๋๋ค. ์๋ก์ด ๊ธด๊ธ ์ ๋ฐ์ดํธ('app')๋ฅผ ์ฐ์ ์ฒ๋ฆฌํ ๋ค์, ์ต์ ์ง์ฐ๋ ๊ฐ์ผ๋ก ์๋ก์ด ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ ๋๋ง์ ์์ฝํฉ๋๋ค.
์ด๋ฅผ ํตํด ๋น์ฉ์ด ๋ง์ด ๋๋ ์์ ์ ํญ์ ๊ฐ์ฅ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ํ๋๋ฉฐ, ์ฌ์ฉ์์ ์๋ก์ด ์ ๋ ฅ์ ์ ๋ ๋ง์ง ์์ต๋๋ค. ์ด๊ฒ์ ๋ณต์กํ ์๋ ๋๋ฐ์ด์ฑ์ด๋ ์ฐ๋กํ๋ง ๋ก์ง ์์ด ๋ฌด๊ฑฐ์ด ๊ณ์ฐ์ ์ฐ์ ์์๋ฅผ ๋ฎ์ถ๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ๋๋ค.
์ค์ฉ์ ์ธ ๊ตฌํ: ๋๋ฆฐ ๊ฒ์ ๊ธฐ๋ฅ ๊ฐ์ ํ๊ธฐ
์ด์ ์์ ๋ฅผ useDeferredValue๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌํฉํ ๋งํ๊ณ ์ค์ ๋์์ ํ์ธํด ๋ด ์๋ค.
ํ์ผ: SearchPage.js (์ต์ ํ๋จ)
import React, { useState, useDeferredValue, useMemo } from 'react';
import ProductList from './ProductList';
import { generateProducts } from './data';
const allProducts = generateProducts(20000);
// ์ฑ๋ฅ์ ์ํด ๋ฉ๋ชจ์ด์ ์ด์
๋ ๋ชฉ๋ก ํ์ ์ปดํฌ๋ํธ
const MemoizedProductList = React.memo(ProductList);
function SearchPage() {
const [query, setQuery] = useState('');
// 1. query ๊ฐ์ ์ง์ฐ์ํต๋๋ค. ์ด ๊ฐ์ 'query' ์ํ๋ณด๋ค ๋ค์ฒ์ง๊ฒ ๋ฉ๋๋ค.
const deferredQuery = useDeferredValue(query);
// 2. ๋น์ฉ์ด ๋ง์ด ๋๋ ํํฐ๋ง์ ์ด์ deferredQuery์ ์ํด ๊ตฌ๋๋ฉ๋๋ค.
// ์ถ๊ฐ ์ต์ ํ๋ฅผ ์ํด useMemo๋ก ๊ฐ์๋๋ค.
const filteredProducts = useMemo(() => {
console.log('Filtering for:', deferredQuery);
return allProducts.filter(product => {
return product.name.toLowerCase().includes(deferredQuery.toLowerCase());
});
}, [deferredQuery]); // deferredQuery๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ๋ค์ ๊ณ์ฐ๋ฉ๋๋ค.
function handleChange(e) {
// ์ด ์ํ ์
๋ฐ์ดํธ๋ ๊ธด๊ธํ๋ฉฐ ์ฆ์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
setQuery(e.target.value);
}
return (
์ฌ์ฉ์ ๊ฒฝํ์ ๋ณํ
์ด ๊ฐ๋จํ ๋ณ๊ฒฝ๋ง์ผ๋ก ์ฌ์ฉ์ ๊ฒฝํ์ ์์ ํ ๋ฐ๋๋๋ค:
- ์ฌ์ฉ์๊ฐ ์ ๋ ฅ ํ๋์ ํ์ดํํ๋ฉด, ํ ์คํธ๊ฐ ์ง์ฐ ์์ด ์ฆ์ ๋ํ๋ฉ๋๋ค. ์ด๋ ์ ๋ ฅ์ value๊ฐ ๊ธด๊ธ ์ ๋ฐ์ดํธ์ธ query ์ํ์ ์ง์ ์ฐ๊ฒฐ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ์๋์ ์ํ ๋ชฉ๋ก์ ๋ฐ๋ผ์ค๋ ๋ฐ ์์ฃผ ์ฝ๊ฐ์ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ง๋ง, ๊ทธ ๋ ๋๋ง ๊ณผ์ ์ด ์ ๋ ฅ ํ๋๋ฅผ ์ ๋ ๋ง์ง ์์ต๋๋ค.
- ์ฌ์ฉ์๊ฐ ๋น ๋ฅด๊ฒ ํ์ดํํ๋ฉด, React๊ฐ ์ค๊ฐ์ ์ค๋๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ ๋๋ง์ ํ๊ธฐํ๋ฏ๋ก ๋ชฉ๋ก์ ๋งจ ๋ง์ง๋ง ์ต์ข ๊ฒ์์ด๋ก ํ ๋ฒ๋ง ์ ๋ฐ์ดํธ๋ ์ ์์ต๋๋ค.
์ด์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ํจ์ฌ ๋ ๋น ๋ฅด๊ณ ์ ๋ฌธ์ ์ผ๋ก ๋๊ปด์ง๋๋ค.
`useDeferredValue` vs. `useTransition`: ์ฐจ์ด์ ์ ๋ฌด์์ผ๊น์?
์ด๋ ๋์์ฑ React๋ฅผ ๋ฐฐ์ฐ๋ ๊ฐ๋ฐ์๋ค์ด ๊ฐ์ฅ ํํ๊ฒ ํผ๋์ค๋ฌ์ํ๋ ๋ถ๋ถ ์ค ํ๋์ ๋๋ค. useDeferredValue์ useTransition ๋ชจ๋ ์ ๋ฐ์ดํธ๋ฅผ ๊ธด๊ธํ์ง ์์ ๊ฒ์ผ๋ก ํ์ํ๋ ๋ฐ ์ฌ์ฉ๋์ง๋ง, ์๋ก ๋ค๋ฅธ ์ํฉ์ ์ ์ฉ๋ฉ๋๋ค.
ํต์ฌ์ ์ธ ์ฐจ์ด์ ์ ์ด๋๋ฅผ ์ ์ดํ ์ ์๋๊ฐ?์ ๋๋ค.
`useTransition`
useTransition์ ์ํ ์ ๋ฐ์ดํธ๋ฅผ ์ ๋ฐํ๋ ์ฝ๋๋ฅผ ์ง์ ์ ์ดํ ์ ์์ ๋ ์ฌ์ฉํฉ๋๋ค. ์ด ํ ์ ๋ณดํต startTransition์ด๋ผ๊ณ ๋ถ๋ฆฌ๋ ํจ์๋ฅผ ์ ๊ณตํ์ฌ ์ํ ์ ๋ฐ์ดํธ๋ฅผ ๊ฐ์ ์ ์๊ฒ ํด์ค๋๋ค.
const [isPending, startTransition] = useTransition();
function handleChange(e) {
const nextValue = e.target.value;
// ๊ธด๊ธํ ๋ถ๋ถ์ ์ฆ์ ์
๋ฐ์ดํธ
setInputValue(nextValue);
// ๋๋ฆฐ ์
๋ฐ์ดํธ๋ startTransition์ผ๋ก ๊ฐ์ธ๊ธฐ
startTransition(() => {
setSearchQuery(nextValue);
});
}
- ์ฌ์ฉ ์์ : ์ํ๋ฅผ ์ง์ ์ค์ ํ๊ณ setState ํธ์ถ์ ๊ฐ์ ์ ์์ ๋.
- ์ฃผ์ ํน์ง: isPending์ด๋ผ๋ ๋ถ๋ฆฌ์ธ(boolean) ํ๋๊ทธ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์ ํ์ด ์ฒ๋ฆฌ๋๋ ๋์ ๋ก๋ฉ ์คํผ๋๋ ๋ค๋ฅธ ํผ๋๋ฐฑ์ ๋ณด์ฌ์ฃผ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
`useDeferredValue`
useDeferredValue๋ ๊ฐ์ ์ ๋ฐ์ดํธํ๋ ์ฝ๋๋ฅผ ์ ์ดํ ์ ์์ ๋ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฐ์ด props์์ ์ค๊ฑฐ๋, ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก๋ถํฐ ์ค๊ฑฐ๋, ๋๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ ๋ค๋ฅธ ํ ์์ ์ฌ ๋ ์์ฃผ ๋ฐ์ํฉ๋๋ค.
function SlowList({ valueFromParent }) {
// valueFromParent๊ฐ ์ด๋ป๊ฒ ์ค์ ๋๋์ง ์ ์ดํ ์ ์์ต๋๋ค.
// ๋จ์ง ๊ฐ์ ๋ฐ์์ ๊ทธ๊ฒ์ ๊ธฐ๋ฐ์ผ๋ก ๋ ๋๋ง์ ์ง์ฐ์ํค๊ณ ์ถ์ ๋ฟ์
๋๋ค.
const deferredValue = useDeferredValue(valueFromParent);
// ... deferredValue๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ์ ๋๋ฆฐ ๋ถ๋ถ์ ๋ ๋๋งํฉ๋๋ค.
}
- ์ฌ์ฉ ์์ : ์ต์ข ๊ฐ๋ง ๊ฐ์ง๊ณ ์๊ณ ๊ทธ๊ฒ์ ์ค์ ํ ์ฝ๋๋ฅผ ๊ฐ์ ์ ์์ ๋.
- ์ฃผ์ ํน์ง: ๋ "๋ฐ์์ ์ธ" ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ด๋์ ์๋์ง์ ์๊ด์์ด ๊ฐ์ด ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋จ์ํ ๋ฐ์ํฉ๋๋ค. ๋ด์ฅ๋ isPending ํ๋๊ทธ๋ ์ ๊ณตํ์ง ์์ง๋ง, ์ง์ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
๋น๊ต ์์ฝ
๊ธฐ๋ฅ | `useTransition` | `useDeferredValue` |
---|---|---|
๋ฌด์์ ๊ฐ์ธ๋๊ฐ | ์ํ ์
๋ฐ์ดํธ ํจ์ (์: startTransition(() => setState(...)) ) |
๊ฐ (์: useDeferredValue(myValue) ) |
์ ์ด ์ง์ | ์ ๋ฐ์ดํธ๋ฅผ ์ํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ ์ดํ ์ ์์ ๋. | ๊ฐ(์: props)์ ๋ฐ๊ณ ๊ทธ ์ถ์ฒ๋ฅผ ์ ์ดํ ์ ์์ ๋. |
๋ก๋ฉ ์ํ | ๋ด์ฅ๋ `isPending` ๋ถ๋ฆฌ์ธ(boolean)์ ์ ๊ณต. | ๋ด์ฅ ํ๋๊ทธ ์์, ํ์ง๋ง `const isStale = originalValue !== deferredValue;`๋ก ํ์ ๊ฐ๋ฅ. |
๋น์ | ๋น์ ์ ์ด๋ค ๊ธฐ์ฐจ(์ํ ์ ๋ฐ์ดํธ)๋ฅผ ๋๋ฆฐ ์ ๋ก๋ก ๋ณด๋ผ์ง ๊ฒฐ์ ํ๋ ๊ด์ ์ฌ์ ๋๋ค. | ๋น์ ์ ๊ธฐ์ฐจ๋ก ๋์ฐฉํ ๊ฐ์ ๋ณด๊ณ , ์ค์ ์ ๊ดํ์ ํ์ํ๊ธฐ ์ ์ ์ญ์ ์ ์ ๋ณด๊ดํ ์ง ๊ฒฐ์ ํ๋ ์ญ์ฅ์ ๋๋ค. |
๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก ๋ฐ ํจํด
๋จ์ํ ๋ชฉ๋ก ํํฐ๋ง์ ๋์ด, useDeferredValue๋ ์ ๊ตํ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๊ฐ๋ ฅํ ํจํด์ ์ ๊ณตํฉ๋๋ค.
ํจํด 1: ํผ๋๋ฐฑ์ผ๋ก "์ค๋๋(Stale)" UI ๋ณด์ฌ์ฃผ๊ธฐ
์๊ฐ์ ํผ๋๋ฐฑ ์์ด ์ฝ๊ฐ์ ์ง์ฐ๊ณผ ํจ๊ป ์ ๋ฐ์ดํธ๋๋ UI๋ ์ฌ์ฉ์์๊ฒ ๋ฒ๊ทธ์ฒ๋ผ ๋๊ปด์ง ์ ์์ต๋๋ค. ์ฌ์ฉ์๋ ์์ ์ ์ ๋ ฅ์ด ๋ฑ๋ก๋์๋์ง ์์ํดํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๊ฐ ์ ๋ฐ์ดํธ ์ค์ด๋ผ๋ ๋ฏธ๋ฌํ ์ ํธ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ข์ ํจํด์ ๋๋ค.
์๋ณธ ๊ฐ๊ณผ ์ง์ฐ๋ ๊ฐ์ ๋น๊ตํ์ฌ ์ด๋ฅผ ๋ฌ์ฑํ ์ ์์ต๋๋ค. ๋ง์ฝ ๋ ๊ฐ์ด ๋ค๋ฅด๋ฉด, ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ ๋๋ง์ด ๋๊ธฐ ์ค์ด๋ผ๋ ์๋ฏธ์ ๋๋ค.
function SearchPage() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
// ์ด ๋ถ๋ฆฌ์ธ ๊ฐ์ ๋ชฉ๋ก์ด ์
๋ ฅ๋ณด๋ค ๋ค์ฒ์ง๊ณ ์๋์ง ์๋ ค์ค๋๋ค.
const isStale = query !== deferredQuery;
const filteredProducts = useMemo(() => {
// ... deferredQuery๋ฅผ ์ฌ์ฉํ ๋น์ฉ์ด ๋ง์ด ๋๋ ํํฐ๋ง
}, [deferredQuery]);
return (
์ด ์์ ์์๋ ์ฌ์ฉ์๊ฐ ํ์ดํํ๋ ์ฆ์ isStale์ด true๊ฐ ๋ฉ๋๋ค. ๋ชฉ๋ก์ด ์ฝ๊ฐ ํ๋ ค์ง๋ฉด์ ์ ๋ฐ์ดํธ๋ ๊ฒ์์ ๋ํ๋ ๋๋ค. ์ง์ฐ๋ ๋ ๋๋ง์ด ์๋ฃ๋๋ฉด query์ deferredQuery๊ฐ ๋ค์ ๊ฐ์์ง๊ณ , isStale์ false๊ฐ ๋๋ฉฐ, ๋ชฉ๋ก์ ์๋ก์ด ๋ฐ์ดํฐ์ ํจ๊ป ์์ ํ ๋ถํฌ๋ช ๋๋ก ๋์์ต๋๋ค. ์ด๊ฒ์ useTransition์ isPending ํ๋๊ทธ์ ๋์ผํ ์ญํ ์ ํฉ๋๋ค.
ํจํด 2: ์ฐจํธ ๋ฐ ์๊ฐํ ์ ๋ฐ์ดํธ ์ง์ฐ์ํค๊ธฐ
๋ ์ง ๋ฒ์๋ฅผ ์ํ ์ฌ์ฉ์ ์ ์ด ์ฌ๋ผ์ด๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฆฌ๋ ๋๋ง๋๋ ์ง๋ฆฌ์ ์ง๋๋ ๊ธ์ต ์ฐจํธ์ ๊ฐ์ ๋ณต์กํ ๋ฐ์ดํฐ ์๊ฐํ๋ฅผ ์์ํด ๋ณด์ธ์. ์ฌ๋ผ์ด๋๋ฅผ ๋๋๊ทธํ ๋๋ง๋ค, ์ฆ ์์ง์ด๋ ๋ชจ๋ ํฝ์ ๋ง๋ค ์ฐจํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๋ค๋ฉด ๋งค์ฐ ๋ฒ๋ฒ ๊ฑฐ๋ฆด ์ ์์ต๋๋ค.
์ฌ๋ผ์ด๋์ ๊ฐ์ ์ง์ฐ์ํด์ผ๋ก์จ, ์ฌ๋ผ์ด๋ ํธ๋ค ์์ฒด๋ ๋ถ๋๋ฝ๊ณ ๋ฐ์์ฑ์ ์ ์งํ๋ฉด์, ๋ฌด๊ฑฐ์ด ์ฐจํธ ์ปดํฌ๋ํธ๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ถ๋๋ฝ๊ฒ ๋ฆฌ๋ ๋๋ง๋๋๋ก ํ ์ ์์ต๋๋ค.
function ChartDashboard() {
const [year, setYear] = useState(2023);
const deferredYear = useDeferredValue(year);
// HeavyChart๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ณ์ฐ์ ์ํํ๋ ๋ฉ๋ชจ์ด์ ์ด์
๋ ์ปดํฌ๋ํธ์
๋๋ค.
// deferredYear ๊ฐ์ด ์์ ๋ ๋๋ง ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.
const chartData = useMemo(() => computeChartData(deferredYear), [deferredYear]);
return (
๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ํํ ํจ์
๊ฐ๋ ฅํ์ง๋ง, useDeferredValue๋ ์ ์คํ๊ฒ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๋ค์์ ๋ฐ๋ผ์ผ ํ ๋ช ๊ฐ์ง ํต์ฌ ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค:
- ๋จผ์ ํ๋กํ์ผ๋ง, ๋์ค์ ์ต์ ํ: useDeferredValue๋ฅผ ๋ชจ๋ ๊ณณ์ ๋จ์ฉํ์ง ๋ง์ธ์. React ๊ฐ๋ฐ์ ๋๊ตฌ ํ๋กํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ์ธ์. ์ด ํ ์ ๋ฆฌ๋ ๋๋ง์ด ์ ๋ง๋ก ๋๋ ค์ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๋ฐํ๋ ์ํฉ์ ํนํ๋์ด ์์ต๋๋ค.
- ์ง์ฐ๋ ์ปดํฌ๋ํธ๋ ํญ์ ๋ฉ๋ชจ์ด์ ์ด์ ํ๊ธฐ: ๊ฐ์ ์ง์ฐ์ํค๋ ์ฃผ๋ ์ด์ ์ ๋ถํ์ํ๊ฒ ๋๋ฆฐ ์ปดํฌ๋ํธ๋ฅผ ๋ฆฌ๋ ๋๋งํ๋ ๊ฒ์ ํผํ๋ ๊ฒ์ ๋๋ค. ์ด ์ด์ ์ ๋๋ฆฐ ์ปดํฌ๋ํธ๊ฐ React.memo๋ก ๊ฐ์ธ์ ธ ์์ ๋ ์์ ํ ์คํ๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ปดํฌ๋ํธ์ props(์ง์ฐ๋ ๊ฐ ํฌํจ)๊ฐ ์ค์ ๋ก ๋ณ๊ฒฝ๋ ๋๋ง ๋ฆฌ๋ ๋๋ง๋๊ณ , ์ง์ฐ๋ ๊ฐ์ด ์์ง ์ด์ ๊ฐ์ธ ์ด๊ธฐ ๊ณ ์ฐ์ ์์ ๋ ๋๋ง ์ค์๋ ๋ฆฌ๋ ๋๋ง๋์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์ฌ์ฉ์ ํผ๋๋ฐฑ ์ ๊ณตํ๊ธฐ: "์ค๋๋ UI" ํจํด์์ ๋ ผ์ํ๋ฏ์ด, ์ด๋ค ํํ์ ์๊ฐ์ ์ ํธ๋ ์์ด UI๊ฐ ์ง์ฐ๋์ด ์ ๋ฐ์ดํธ๋๋๋ก ๋์ง ๋ง์ธ์. ํผ๋๋ฐฑ์ ๋ถ์ฌ๋ ์๋์ ์ง์ฐ๋ณด๋ค ๋ ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค.
- ์ ๋ ฅ ๊ฐ ์์ฒด๋ฅผ ์ง์ฐ์ํค์ง ์๊ธฐ: ํํ ์ค์๋ ์ ๋ ฅ์ ์ ์ดํ๋ ๊ฐ์ ์ง์ฐ์ํค๋ ค๊ณ ํ๋ ๊ฒ์ ๋๋ค. ์ ๋ ฅ์ value prop์ ์ฆ๊ฐ์ ์ธ ๋๋์ ๋ณด์ฅํ๊ธฐ ์ํด ํญ์ ๊ณ ์ฐ์ ์์ ์ํ์ ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค. ๋๋ฆฐ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋๋ ๊ฐ์ ์ง์ฐ์์ผ์ผ ํฉ๋๋ค.
- `timeoutMs` ์ต์
์ดํดํ๊ธฐ (์ฃผ์ํด์ ์ฌ์ฉ): useDeferredValue๋ ํ์์์์ ์ํ ์ ํ์ ๋ ๋ฒ์งธ ์ธ์๋ฅผ ๋ฐ์ต๋๋ค:
useDeferredValue(value, { timeoutMs: 500 })
. ์ด๊ฒ์ React์๊ฒ ๊ฐ์ ์ง์ฐ์์ผ์ผ ํ๋ ์ต๋ ์๊ฐ์ ์๋ ค์ค๋๋ค. ์ผ๋ถ ๊ฒฝ์ฐ์ ์ ์ฉํ ์ ์๋ ๊ณ ๊ธ ๊ธฐ๋ฅ์ด์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก๋ React๊ฐ ์ฅ์น ์ฑ๋ฅ์ ๋ง๊ฒ ์ต์ ํ๋ ํ์ด๋ฐ์ ๊ด๋ฆฌํ๋๋ก ๋๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค.
๊ธ๋ก๋ฒ ์ฌ์ฉ์ ๊ฒฝํ(UX)์ ๋ฏธ์น๋ ์ํฅ
useDeferredValue์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฑํํ๋ ๊ฒ์ ๋จ์ํ ๊ธฐ์ ์ ์ธ ์ต์ ํ๊ฐ ์๋๋๋ค; ์ด๋ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํ ๋ ์ข๊ณ ํฌ์ฉ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ํ ์ฝ์์ ๋๋ค.
- ์ฅ์น ํํ์ฑ(Device Equity): ๊ฐ๋ฐ์๋ค์ ์ข ์ข ๊ณ ์ฌ์ ์ปดํจํฐ์์ ์์ ํฉ๋๋ค. ์ต์ ๋ ธํธ๋ถ์์๋ ๋น ๋ฅด๊ฒ ๋๊ปด์ง๋ UI๊ฐ, ์ธ๊ณ ์ธ๊ตฌ์ ์๋น ๋ถ๋ถ์ด ์ฃผ ์ธํฐ๋ท ์ฅ์น๋ก ์ฌ์ฉํ๋ ๊ตฌํ ์ ์ฌ์ ํด๋ํฐ์์๋ ์ฌ์ฉ ๋ถ๊ฐ๋ฅํ ์ ์์ต๋๋ค. ๋ ผ๋ธ๋กํน ๋ ๋๋ง์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ๋์ ๋ฒ์์ ํ๋์จ์ด์์ ๋ ํ๋ ฅ์ ์ด๊ณ ์ฑ๋ฅ ์ข๊ฒ ๋ง๋ญ๋๋ค.
- ์ ๊ทผ์ฑ ํฅ์: ๋ฉ์ถ๋ UI๋ ์คํฌ๋ฆฐ ๋ฆฌ๋ ๋ฐ ๊ธฐํ ๋ณด์กฐ ๊ธฐ์ ์ฌ์ฉ์์๊ฒ ํนํ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฌ์ ๋กญ๊ฒ ์ ์งํ๋ฉด ์ด๋ฌํ ๋๊ตฌ๋ค์ด ๊ณ์ ์ํํ๊ฒ ์๋ํ์ฌ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๋ ์์ ์ ์ด๊ณ ๋ ๋ต๋ตํ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
- ํฅ์๋ ์ธ์ง ์ฑ๋ฅ(Perceived Performance): ์ฌ๋ฆฌํ์ ์ฌ์ฉ์ ๊ฒฝํ์์ ํฐ ์ญํ ์ ํฉ๋๋ค. ํ๋ฉด์ ์ผ๋ถ๊ฐ ์ ๋ฐ์ดํธ๋๋ ๋ฐ ์๊ฐ์ด ์ข ๊ฑธ๋ฆฌ๋๋ผ๋ ์ ๋ ฅ์ ์ฆ์ ๋ฐ์ํ๋ ์ธํฐํ์ด์ค๋ ํ๋์ ์ด๊ณ , ์ ๋ขฐํ ์ ์์ผ๋ฉฐ, ์ ๋ง๋ค์ด์ง ๋๋์ ์ค๋๋ค. ์ด๋ ๊ฒ ์ธ์ง๋ ์๋๋ ์ฌ์ฉ์ ์ ๋ขฐ์ ๋ง์กฑ๋๋ฅผ ๋์ ๋๋ค.
๊ฒฐ๋ก
React์ useDeferredValue ํ ์ ์ฑ๋ฅ ์ต์ ํ์ ์ ๊ทผํ๋ ๋ฐฉ์์ ํจ๋ฌ๋ค์ ์ ํ์ ๋๋ค. ๋๋ฐ์ด์ฑ์ด๋ ์ฐ๋กํ๋ง๊ณผ ๊ฐ์ด ์๋์ ์ด๊ณ ์ข ์ข ๋ณต์กํ ๊ธฐ์ ์ ์์กดํ๋ ๋์ , ์ด์ ์ฐ๋ฆฌ๋ ์ ์ธ์ ์ผ๋ก React์๊ฒ ์ฐ๋ฆฌ UI์ ์ด๋ค ๋ถ๋ถ์ด ๋ ์ค์ํ์ง ์๋ ค์ค ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด React๊ฐ ํจ์ฌ ๋ ์ง๋ฅ์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฐฉ์์ผ๋ก ๋ ๋๋ง ์์ ์ ์ค์ผ์ค๋งํ ์ ์๊ฒ ๋ฉ๋๋ค.
๋์์ฑ์ ํต์ฌ ์์น์ ์ดํดํ๊ณ , useDeferredValue์ useTransition์ ์ธ์ ์ฌ์ฉํด์ผ ํ๋์ง ์๋ฉฐ, ๋ฉ๋ชจ์ด์ ์ด์ ๊ณผ ์ฌ์ฉ์ ํผ๋๋ฐฑ๊ณผ ๊ฐ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ์ฉํจ์ผ๋ก์จ, UI ๋ฒ๋ฒ ์(jank)์ ์ ๊ฑฐํ๊ณ ๊ธฐ๋ฅ์ ์ผ ๋ฟ๋ง ์๋๋ผ ์ฌ์ฉํ๊ธฐ ์ฆ๊ฑฐ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๊ฒฝ์์ด ์น์ดํ ๊ธ๋ก๋ฒ ์์ฅ์์ ๋น ๋ฅด๊ณ , ๋ฐ์์ฑ์ด ์ข์ผ๋ฉฐ, ์ ๊ทผ ๊ฐ๋ฅํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๊ฒ์ด ์ต๊ณ ์ ๊ธฐ๋ฅ์ด๋ฉฐ, useDeferredValue๋ ์ด๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ ์ฌ๋ฌ๋ถ์ ๋ฌด๊ธฐ๊ณ ์์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๋๊ตฌ ์ค ํ๋์ ๋๋ค.